package  com.sat.common.base

import android.app.Dialog
import android.content.pm.ActivityInfo
import android.graphics.Color
import android.os.Bundle
import android.text.TextUtils
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.sat.common.R
import com.sat.common.bean.EventBusMessage
import com.sat.common.bean.Message
import com.sat.common.bean.MessageCode
import com.sat.common.utils.ViewModelFactory
import com.sat.common.widget.LoadingDialog
import com.sat.common.widget.LoadingDialogUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.lang.reflect.ParameterizedType

abstract class BaseActivity<VM : BaseViewModel, DB : ViewDataBinding> : AppCompatActivity() {

    protected lateinit var viewModel: VM

    protected var mBinding: DB? = null

    private var dialog: Dialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
//        val insertControllerCompat = WindowCompat.getInsetsController(window, window.decorView)!!
        //insertControllerCompat?.show(WindowInsetsCompat.Type.systemBars()) // 展示系统view：状态栏+导航栏+系统标题栏。在使用getInsetsController后，
        //需先在xml styles隐藏actionBar（系统标题栏），不要用代码（如getSupportActionBar()?.hide()等）设置该系统标题栏隐藏，且insetsController不能单独隐藏系统标题栏
        //insertControllerCompat?.hide(WindowInsetsCompat.Type.navigationBars()) //隐藏底部手势导航栏
        //insertControllerCompat?.hide(WindowInsetsCompat.Type.statusBars())  //隐藏状态栏
//        WindowCompat.setDecorFitsSystemWindows(window, false) // 页面布局是否在状态栏下方，false：侵入状态栏
//        insertControllerCompat.isAppearanceLightStatusBars = true //状态栏字体明暗主题，true为黑色（默认黑色），false为白色
//        window.statusBarColor = Color.TRANSPARENT //状态栏背景色，侵入时最好设置为透明
        initViewDataBinding()
        lifecycle.addObserver(viewModel)
        //注册 UI事件
        registorDefUIChange()
        EventBus.getDefault().register(this)
        initView(savedInstanceState)
        initListener()
        initData()

    }

    abstract fun layoutId(): Int
    abstract fun initView(savedInstanceState: Bundle?)
    abstract fun initData()
    abstract fun initListener()

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
    }

    /**
     * DataBinding
     */
    private fun initViewDataBinding() {
        val cls =
            (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<*>
        if (ViewDataBinding::class.java != cls && ViewDataBinding::class.java.isAssignableFrom(cls)) {
            mBinding = DataBindingUtil.setContentView(this, layoutId())
            mBinding?.lifecycleOwner = this
        } else setContentView(layoutId())
        createViewModel()
    }


    /**
     * 注册 UI 事件
     */
    private fun registorDefUIChange() {
        viewModel.defUI.showDialog.observe(this, Observer {
            if (TextUtils.isEmpty(it)) {
                showLoading()
            } else {
                showLoading(it!!)
            }

        })
        viewModel.defUI.dismissDialog.observe(this, Observer {
            dismissLoading()
        })
        viewModel.defUI.toastEvent.observe(this, Observer {
            showToast(it)
        })
        viewModel.defUI.msgEvent.observe(this, Observer {
            handleEvent(it)
        })
    }

    open fun handleEvent(msg: Message) {}

    /**
     * 打开等待框
     */
    fun showLoading(msg: String = getString(R.string.loading)) {
        if (dialog == null) {
            dialog = LoadingDialog(this)

        }
        dialog?.show()

    }

    /**
     * 关闭等待框
     */
    fun dismissLoading() {
        dialog?.run { if (isShowing) dismiss() }
    }


    /**
     * 创建 ViewModel
     */
    @Suppress("UNCHECKED_CAST")
    private fun createViewModel() {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val tp = type.actualTypeArguments[0]
            val tClass = tp as? Class<VM> ?: BaseViewModel::class.java
            viewModel = ViewModelProvider(this, ViewModelFactory()).get(tClass) as VM
        }
    }

    fun showToast(msg: String) {
        showToast(msg, Toast.LENGTH_SHORT)
    }

    fun showToast(msg: String, duration: Int) {
        Toast.makeText(this, msg, duration).show()
    }

    fun showToast(resourceId: Int) {
        showToast(resourceId, Toast.LENGTH_SHORT)
    }

    fun showToast(resourceId: Int, duration: Int) {
        showToast(getString(resourceId), duration)
    }

    @Subscribe
    open fun handleEventBus(msg: EventBusMessage) {
        when (msg.code) {
            MessageCode.FINISH_ACTIVITY -> {
                finish()
            }
        }
    }
}